//@ sourceMappingURL=jquery.caret.map
/*
 Implement Github like autocomplete mentions
 http://ichord.github.com/At.js

 Copyright (c) 2013 chord.luo@gmail.com
 Licensed under the MIT license.
 */


/*
 本插件操作 textarea 或者 input 内的插入符
 只实现了获得插入符在文本框中的位置，我设置
 插入符的位置.
 */


(function () {
    (function (factory) {
        if (typeof define === 'function' && define.amd) {
            return define(['jquery'], factory);
        } else {
            return factory(window.jQuery);
        }
    })(function ($) {
        "use strict";
        var EditableCaret, InputCaret, Mirror, Utils, methods, oDocument, oFrame, oWindow, pluginName;
        pluginName = 'caret';
        EditableCaret = (function () {
            function EditableCaret ($inputor) {
                this.$inputor = $inputor;
                this.domInputor = this.$inputor[0];
            }

            EditableCaret.prototype.setPos = function (pos) {
                return this.domInputor;
            };

            EditableCaret.prototype.getIEPosition = function () {
                return $.noop();
            };

            EditableCaret.prototype.getPosition = function () {
                return $.noop();
            };

            EditableCaret.prototype.getOldIEPos = function () {
                var preCaretTextRange, textRange;
                textRange = oDocument.selection.createRange();
                preCaretTextRange = oDocument.body.createTextRange();
                preCaretTextRange.moveToElementText(this.domInputor);
                preCaretTextRange.setEndPoint("EndToEnd", textRange);
                return preCaretTextRange.text.length;
            };

            EditableCaret.prototype.getPos = function () {
                var clonedRange, pos, range;
                if (range = this.range()) {
                    clonedRange = range.cloneRange();
                    clonedRange.selectNodeContents(this.domInputor);
                    clonedRange.setEnd(range.endContainer, range.endOffset);
                    pos = clonedRange.toString().length;
                    clonedRange.detach();
                    return pos;
                } else if (oDocument.selection) {
                    return this.getOldIEPos();
                }
            };

            EditableCaret.prototype.getOldIEOffset = function () {
                var range, rect;
                range = oDocument.selection.createRange().duplicate();
                range.moveStart("character", -1);
                rect = range.getBoundingClientRect();
                return {
                    height: rect.bottom - rect.top,
                    left: rect.left,
                    top: rect.top
                };
            };

            EditableCaret.prototype.getOffset = function (pos) {
                var clonedRange, offset, range, rect;
                if (oWindow.getSelection && (range = this.range())) {
                    if (range.endOffset - 1 < 0) {
                        return null;
                    }
                    clonedRange = range.cloneRange();
                    clonedRange.setStart(range.endContainer, range.endOffset - 1);
                    clonedRange.setEnd(range.endContainer, range.endOffset);
                    rect = clonedRange.getBoundingClientRect();
                    offset = {
                        height: rect.height,
                        left: rect.left + rect.width,
                        top: rect.top
                    };
                    clonedRange.detach();
                } else if (oDocument.selection) {
                    offset = this.getOldIEOffset();
                }
                if (offset && !oFrame) {
                    offset.top += $(oWindow).scrollTop();
                    offset.left += $(oWindow).scrollLeft();
                }
                return offset;
            };

            EditableCaret.prototype.range = function () {
                var sel;
                if (!oWindow.getSelection) {
                    return;
                }
                sel = oWindow.getSelection();
                if (sel.rangeCount > 0) {
                    return sel.getRangeAt(0);
                } else {
                    return null;
                }
            };

            return EditableCaret;

        })();
        InputCaret = (function () {
            function InputCaret ($inputor) {
                this.$inputor = $inputor;
                this.domInputor = this.$inputor[0];
            }

            InputCaret.prototype.getIEPos = function () {
                var endRange, inputor, len, normalizedValue, pos, range, textInputRange;
                inputor = this.domInputor;
                range = oDocument.selection.createRange();
                pos = 0;
                if (range && range.parentElement() === inputor) {
                    normalizedValue = inputor.value.replace(/\r\n/g, "\n");
                    len = normalizedValue.length;
                    textInputRange = inputor.createTextRange();
                    textInputRange.moveToBookmark(range.getBookmark());
                    endRange = inputor.createTextRange();
                    endRange.collapse(false);
                    if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                        pos = len;
                    } else {
                        pos = -textInputRange.moveStart("character", -len);
                    }
                }
                return pos;
            };

            InputCaret.prototype.getPos = function () {
                if (oDocument.selection) {
                    return this.getIEPos();
                } else {
                    return this.domInputor.selectionStart;
                }
            };

            InputCaret.prototype.setPos = function (pos) {
                var inputor, range;
                inputor = this.domInputor;
                if (oDocument.selection) {
                    range = inputor.createTextRange();
                    range.move("character", pos);
                    range.select();
                } else if (inputor.setSelectionRange) {
                    inputor.setSelectionRange(pos, pos);
                }
                return inputor;
            };

            InputCaret.prototype.getIEOffset = function (pos) {
                var h, textRange, x, y;
                textRange = this.domInputor.createTextRange();
                pos || (pos = this.getPos());
                textRange.move('character', pos);
                x = textRange.boundingLeft;
                y = textRange.boundingTop;
                h = textRange.boundingHeight;
                return {
                    left: x,
                    top: y,
                    height: h
                };
            };

            InputCaret.prototype.getOffset = function (pos) {
                var $inputor, offset, position;
                $inputor = this.$inputor;
                if (oDocument.selection) {
                    offset = this.getIEOffset(pos);
                    offset.top += $(oWindow).scrollTop() + $inputor.scrollTop();
                    offset.left += $(oWindow).scrollLeft() + $inputor.scrollLeft();
                    return offset;
                } else {
                    offset = $inputor.offset();
                    position = this.getPosition(pos);
                    return offset = {
                        left: offset.left + position.left - $inputor.scrollLeft(),
                        top: offset.top + position.top - $inputor.scrollTop(),
                        height: position.height
                    };
                }
            };

            InputCaret.prototype.getPosition = function (pos) {
                var $inputor, at_rect, format, html, mirror, start_range;
                $inputor = this.$inputor;
                format = function (value) {
                    return value.replace(/</g, '&lt').replace(/>/g, '&gt').replace(/`/g, '&#96').replace(/"/g, '&quot').replace(/\r\n|\r|\n/g, "<br />");
                };
                if (pos === void 0) {
                    pos = this.getPos();
                }
                start_range = $inputor.val().slice(0, pos);
                html = "<span>" + format(start_range) + "</span>";
                html += "<span id='caret'>|</span>";
                mirror = new Mirror($inputor);
                return at_rect = mirror.create(html).rect();
            };

            InputCaret.prototype.getIEPosition = function (pos) {
                var h, inputorOffset, offset, x, y;
                offset = this.getIEOffset(pos);
                inputorOffset = this.$inputor.offset();
                x = offset.left - inputorOffset.left;
                y = offset.top - inputorOffset.top;
                h = offset.height;
                return {
                    left: x,
                    top: y,
                    height: h
                };
            };

            return InputCaret;

        })();
        Mirror = (function () {
            Mirror.prototype.css_attr = ["overflowY", "height", "width", "paddingTop", "paddingLeft", "paddingRight", "paddingBottom", "marginTop", "marginLeft", "marginRight", "marginBottom", "fontFamily", "borderStyle", "borderWidth", "wordWrap", "fontSize", "lineHeight", "overflowX", "text-align"];

            function Mirror ($inputor) {
                this.$inputor = $inputor;
            }

            Mirror.prototype.mirrorCss = function () {
                var css,
                    _this = this;
                css = {
                    position: 'absolute',
                    left: -9999,
                    top: 0,
                    zIndex: -20000,
                    'white-space': 'pre-wrap'
                };
                $.each(this.css_attr, function (i, p) {
                    return css[p] = _this.$inputor.css(p);
                });
                return css;
            };

            Mirror.prototype.create = function (html) {
                this.$mirror = $('<div></div>');
                this.$mirror.css(this.mirrorCss());
                this.$mirror.html(html);
                this.$inputor.after(this.$mirror);
                return this;
            };

            Mirror.prototype.rect = function () {
                var $flag, pos, rect;
                $flag = this.$mirror.find("#caret");
                pos = $flag.position();
                rect = {
                    left: pos.left,
                    top: pos.top,
                    height: $flag.height()
                };
                this.$mirror.remove();
                return rect;
            };

            return Mirror;

        })();
        Utils = {
            contentEditable: function ($inputor) {
                return !!($inputor[0].contentEditable && $inputor[0].contentEditable === 'true');
            }
        };
        methods = {
            pos: function (pos) {
                if (pos) {
                    return this.setPos(pos);
                } else {
                    return this.getPos();
                }
            },
            position: function (pos) {
                if (oDocument.selection) {
                    return this.getIEPosition(pos);
                } else {
                    return this.getPosition(pos);
                }
            },
            offset: function (pos) {
                var iOffset, offset;
                offset = this.getOffset(pos);
                if (oFrame) {
                    iOffset = $(oFrame).offset();
                    offset.top += iOffset.top;
                    offset.left += iOffset.left;
                }
                return offset;
            }
        };
        oDocument = null;
        oWindow = null;
        oFrame = null;
        $.fn.caret = function (method) {
            var caret;
            oDocument = this[0].ownerDocument;
            oWindow = oDocument.defaultView || oDocument.parentWindow;
            oFrame = oWindow.frameElement;
            caret = Utils.contentEditable(this) ? new EditableCaret(this) : new InputCaret(this);
            if (methods[method]) {
                return methods[method].apply(caret, Array.prototype.slice.call(arguments, 1));
            } else {
                return $.error("Method " + method + " does not exist on jQuery.caret");
            }
        };
        $.fn.caret.EditableCaret = EditableCaret;
        $.fn.caret.InputCaret = InputCaret;
        $.fn.caret.Utils = Utils;
        return $.fn.caret.apis = methods;
    });

}).call(this);